package vmcs.controller.statePattern;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import vmcs.controller.CustomerController;
import vmcs.controller.StoreController;
import vmcs.entity.CashStoreItem;
import vmcs.entity.Coin;
import vmcs.entity.DrinksBrand;
import vmcs.entity.DrinksStore;
import vmcs.entity.DrinksStoreItem;
import vmcs.entity.StoreItem;
/**
 *
 * @author eileen
 */
public class TransactionController {
    public static final int DRINK_SEL = 0;
    public static final int COIN_RECV = 1;
    public static final int DISPENSE_DRINK = 2;
    public static final int CHANGE_GIVE = 3;
    public static final int STORE_COIN = 4;
    public static final int MAINT = 5;
    public static final int TERMINATE = 6;
    public static final int END_S = 7;
    
    private VmcsState[] states; 
    static private TransactionController m_fsm = null;
    private CustomerController cusCtrl;
    private boolean fault = false;
    private String content;
    private boolean bDrinkPanel;
    private boolean bDCoinPanel;
    private boolean bMaintLogin;
    private int current = 0;
    private String drinkId = null;
    private int price = 0;
    private double coinWeight = 0.0;
    private int refundAmount = 0;

    static public TransactionController instance(){
        if(m_fsm == null){
           m_fsm = new TransactionController(); 
        }
        return m_fsm;
    }
    public void changeState(int index) {
        this.current = index;
    }
    
    public VmcsState getState(int index) {
        return states[index];
    }
    
    public double getCoinWeight() {
        return coinWeight;
    }

    public void setCoinWeight(double coinWeight) {
        this.coinWeight = coinWeight;
    }
    
    public void setCustomerController(CustomerController cusCtrl){
        this.cusCtrl = cusCtrl;
    }
    
    public CustomerController getCustomerController(){
        return cusCtrl;
    }
    
    public double getCurrentCoinValue(){
        CashStoreItem dItem= (CashStoreItem) cusCtrl.getStoreCtrl().getCoinStoreItem(coinWeight);
        double value = 0.0;
        if( dItem != null){
            Coin coin = (Coin)dItem.getContent();
            value = coin.getValue();
            //Increase the coin quantity by 1
            dItem.increaseQuantityByOne();
            setCoinInvalidFlag(false);
        }
        else setCoinInvalidFlag(true);
        return value;
    }
        
    public int getRefundAmount() {
        return refundAmount;
    }

    public void setRefundAmount(int refundAmount) {
        this.refundAmount = refundAmount;
        int remainder = refundAmount;
        //Update the decrement of coins
        if(remainder > 0 ){
            StoreItem[] items = cusCtrl.getStoreCtrl().getStoreItems(StoreController.CASH);
            int size = items.length-1;
            for(int i=size; i>=0; --i ){
                CashStoreItem coinItem = (CashStoreItem)items[i];
                Coin coin = (Coin)coinItem.getContent();
                int val = coin.getValue();
                if( val <= remainder){
                    remainder -= val;
                    coinItem.decreaseQuantityByOne();
                    i++;
                }
            }
        }
        cusCtrl.updateReturnChange(refundAmount);
    }
    
    public void setActivateDrinkPanel(boolean f){
        if(f){
           System.out.println("Drink Panel is activated"); 
        }
        else{
           System.out.println("Drink Panel is not activated"); 
        }
        cusCtrl.setDrinkPanelEnable(f);
        bDrinkPanel = f;
    }
    
    public void setCoinInvalidFlag(boolean f){
        cusCtrl.setCoinInvalidFlag(f);
    }
    
    public void setDrinkDispense(String drink){
        cusCtrl.updateDispenseDrink(drink);
        //Decrease the quantity of drink by 1
         if(drink != null){
            DrinksStoreItem dItem= (DrinksStoreItem) cusCtrl.getStoreCtrl().getDrinkStoreItem(drink);
            dItem.decreaseQuantityByOne();
        }
    }
    
    public boolean getActivateDrinkPanel(){
        return bDrinkPanel;
    }
    
    public void setActivateCoinPanel(boolean f){
        if(f){
           System.out.println("Coin Panel is activated"); 
        }
        else{
           System.out.println("Coin Panel is not activated"); 
        }
        cusCtrl.setCoinPanelEnable(f);
        bDCoinPanel = f;
    }
    
    public void setTotalInsertedValue(int ttlVal){
        cusCtrl.updateTotalCoinInserted(ttlVal);
    }
    
    public boolean getActivateCoinPanel(){
        return bDCoinPanel;
    }
    
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isfault() {
        return fault;
    }

    public void setfault(boolean fault) {
        this.fault = fault;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getDrinkSelection() {
        return drinkId;
    }

    public void clearDrinkSelection() {
        cusCtrl.onClearSelectedDrink();
    }
    
    public void setDrinkSelection(String drink) {
        if(drink != null){
            DrinksStoreItem dItem= (DrinksStoreItem) cusCtrl.getStoreCtrl().getDrinkStoreItem(drink);
            price = dItem.getPrice();
        }
        this.drinkId = drink;
    }
    
    public void OnStartTransaction(String drink) {
        
        // Customer selected drink
        if( (this.drinkId == null) || (!this.drinkId.equals(drink)) ){
            states[current].OnSelectDrink();
            this.setDrinkSelection(drink);
        }
    }
    
    public void OnCoinTransaction(double weight){
        // Customer input coins
        this.coinWeight = weight;
        states[current].OnReceiveCoin();
    }
    
    public void OnResetTransaction(){
        // Customer reset    
        states[current].OnSelectDrink();
        current = DRINK_SEL;
        setActivateCoinPanel(false);
    }
    
    public boolean getMaintenanceFlag(){
        return bMaintLogin;
    }
    
    public void OnMaintenanceTransaction(boolean f){
        // Customer reset      
        if(bMaintLogin != f) {
            bMaintLogin = f;
             if(f){
               System.out.println("Maintenance Panel has login"); 
            }
            else{
               System.out.println("Maintenance Panel has logout"); 
            }
            states[current].OnMaintenance();
        }
    }
    
    public void OnFaultTransaction(){
        // VMCS Faulty    
        states[current].OnTerminate();
    }        
    
    private TransactionController(){
        current = DRINK_SEL;
        states = new VmcsState[END_S];
        states[DRINK_SEL] =  new DrinkSelectionState(this);
        states[COIN_RECV] =  new CoinReceiveState(this);
        states[CHANGE_GIVE] =  new ChangeGiverState(this);
        states[STORE_COIN] =  new StoreCoinState(this);
        states[DISPENSE_DRINK] =  new DispenseDrinkState(this);
        states[MAINT] =  new MaintenanceState(this);
        states[TERMINATE] =  new TerminateState(this);
    }
    
}